package com.hhxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhxy.handler.exception.CustomException;
import com.hhxy.mapper.UserMapper;
import com.hhxy.model.dto.AddUserDto;
import com.hhxy.model.dto.UserInfoDto;
import com.hhxy.model.dto.UserRegisterDto;
import com.hhxy.model.entity.User;
import com.hhxy.model.entity.UserRole;
import com.hhxy.model.vo.PageVo;
import com.hhxy.model.vo.UserInfoVo;
import com.hhxy.model.vo.UserPageInfoVo;
import com.hhxy.service.UserRoleService;
import com.hhxy.service.UserService;
import com.hhxy.utils.BeanCopyUtils;
import com.hhxy.utils.SecurityUtils;
import com.hhxy.utils.response.AppHttpCodeEnum;
import com.hhxy.utils.response.ResponseResult;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ghp
 * @description 针对表【tb_user(用户表)】的数据库操作Service实现
 * @createDate 2023-04-25 11:59:00
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private UserRoleService userRoleService;

    /**
     * 查看用户个人信息
     *
     * @return
     */
    @Override
    public ResponseResult getUserInfo() {
        // 根据userId查看用户信息
        User user = this.getById(SecurityUtils.getUserId());
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        return ResponseResult.okResult(userInfoVo);
    }

    /**
     * 修改个人信息
     *
     * @param userInfoDto
     * @return
     */
    @Override
    public ResponseResult updateUserInfo(UserInfoDto userInfoDto) {
        User user = BeanCopyUtils.copyBean(userInfoDto, User.class);
        user.setId(SecurityUtils.getUserId());
        boolean flag = this.updateById(user);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_UPDATE_ERROR);
        }
        return ResponseResult.okResult();
    }

    /**
     * 用户注册
     *
     * @param userRegisterDto
     * @return
     */
    @Override
    public ResponseResult register(UserRegisterDto userRegisterDto) {
        User user = BeanCopyUtils.copyBean(userRegisterDto, User.class);
        // 判断email、userName字段是否唯一
        if (isUnique("email", user.getEmail())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CLIENT_EMAIL_ERROR);
        }
        if (isUnique("user_name", user.getUserName())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CLIENT_USERNAME_ERROR);
        }

        // email、userName都唯一，可以进行注册（注册前需先对密码进行加密）
        String encryptPassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encryptPassword);
        boolean flag = this.save(user);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SYSTEM_ERROR);
        }
        return ResponseResult.okResult();
    }

    /**
     * 分页条件查询出用户信息
     */
    @Override
    public ResponseResult list(Integer pageNum, Integer pageSize, String userName, String phonenumber, String status) {
        // 分页查询出用户信息
        Page<User> page = new Page<>(pageNum, pageSize);
        this.page(page, new LambdaQueryWrapper<User>()
                .like(StringUtils.hasText(userName), User::getUserName, userName)
                .like(StringUtils.hasText(phonenumber), User::getPhonenumber, phonenumber)
                .eq(StringUtils.hasText(status), User::getStatus, status)
                .orderByDesc(User::getUserName));
        // 转换成VO
        List<UserPageInfoVo> userPageInfoVoList = page.getRecords().stream()
                .map(user -> BeanCopyUtils.copyBean(user, UserPageInfoVo.class))
                .collect(Collectors.toList());
        // 将封装好的VO响应给前端
        return ResponseResult.okResult(new PageVo(userPageInfoVoList, page.getTotal()));
    }

    /**
     * 根据用户id修改用户信息，包括角色信息
     *
     * @param user
     * @return
     */
    @Override
    @Transactional
    public ResponseResult updateUserInfoById(User user) {
        // 删除之前的用户角色关系
        boolean flag = userRoleService.remove(new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, user.getId()));
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_UPDATE_ERROR);
        }
        // 构建新增用户角色关系，并添加到数据库中
        List<UserRole> userRoleList = Arrays.stream(user.getRoleIds())
                .map(roleId -> new UserRole(user.getId(), roleId)).collect(Collectors.toList());
        flag = userRoleService.saveBatch(userRoleList);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_DELETE_ERROR);
        }

        // 更新用户信息
        flag = this.updateById(user);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_DELETE_ERROR);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_DELETE);
    }

    /**
     * 新增用户信息
     *
     * @param addUserDto
     * @return
     */
    @Override
    @Transactional
    public ResponseResult addUser(AddUserDto addUserDto) {
        // 新增用户信息
        //密码加密处理
        addUserDto.setPassword(passwordEncoder.encode(addUserDto.getPassword()));
        User user = BeanCopyUtils.copyBean(addUserDto, User.class);
        boolean flag = save(user);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_INSERT_ERROR);
        }

        // 新增用户-角色关系
        if (user.getRoleIds() != null && user.getRoleIds().length > 0) {
            List<UserRole> sysUserRoles = Arrays.stream(user.getRoleIds())
                    .map(roleId -> new UserRole(user.getId(), roleId)).collect(Collectors.toList());
            flag = userRoleService.saveBatch(sysUserRoles);
            if (!flag) {
                throw new CustomException(AppHttpCodeEnum.SERVICE_INSERT_ERROR);
            }
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_INSERT);
    }

    /**
     * 判断字段的值是否唯一
     *
     * @return true-不唯一 false-唯一
     */
    private boolean isUnique(String fieldName, String email) {
        int count = this.count(new QueryWrapper<User>()
                .eq(fieldName, email));
        return count > 0;
    }
}




